﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WeChatParking.Core;
using WeChatParking.Core.Payment.Tonglian;
using WeChatParking.Core.Payment.WeixinPay;

namespace WeChatParking.Web.Controllers
{
    public class PayController : BaseController
    {
        //
        // GET: /Pay/

        public ActionResult Index(string orderid)
        {
            try
            {
                var orderBll = new Core.BLL.PrepaidOrder();
                var order = orderBll.GetOrder(orderid);
                if (order == null)
                {
                    return View("~/Views/Pay/OrderNotFound.cshtml");
                }
                if (order.pay_status == 3)
                {
                    return View("~/Views/Pay/OrderPaySuccess.cshtml", order);
                }
                ViewBag.WxConfig = GetWxPayConfig();
                //order.EnterpriseID
                //根据物业ID找出对应的物业的支付方式、进入对应的支付流程
                if (WxpayConfig.IsTonglianChannel)
                {
                    //通联支付
                    //return RedirectToAction("Do", "TonglianPay", new { orderid = orderid });
                    var payInfo = NewGetPayInfo(order, base.CurrentOpenId);
                    // ViewBag.WxPayParam = payInfo == null ? string.Empty : Util.Conv.ToJson(payInfo);
                    ViewBag.WxPayParam = payInfo == null ? string.Empty : payInfo;
                    return View(order);
                }
                else
                {
                    string WxPayParam = Util.Conv.ToJson(GetWxPayJSParams(order, base.CurrentOpenId));
                    LogHelper.Info(WxPayParam, "微信支付接口信息");
                    ViewBag.WxPayParam = WxPayParam;
                    return View(order);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex, "订单支付");
                return View("~/Views/Pay/OrderNotFound.cshtml");
            }

        }  
        #region 新通联支付--微信JSAPI
        /// <summary>
        /// 新通联支付的接口
        /// </summary>
        /// <param name="order"></param>
        /// <param name="openid"></param>
        /// <returns></returns>
        private string NewGetPayInfo(Entity.Order_info order, string openid)
        {
            // openid = "oKqp90V4ISTEstdxTfhJ11hEXSSw";
            string payInfo = null;
            Entity.log log = new Entity.log();
            log.business_no = order.order_id;
            log.api_name = "通联下单";
            TonglianNew tlPay = new TonglianNew();
            string floatValue = (order.total_fee * 100).ToString();
            string[] value = floatValue.Split('.');
            long trxamt = long.Parse(value[0]);
            string request = "";
            try
            {
                int port = Request.Url.Port;
                string NotifyUrl = "http://" + Request.Url.Host
                 + (port > 0 && port != 80 ? string.Format(":{0}", port) : string.Empty)
                 + "/Pay/WxpayNotify";
                Dictionary<String, String> rsp = tlPay.pay(trxamt, order.order_id, "W02", "一卡通充值", "", openid, "", NotifyUrl, out request);
                log.request = request;
                log.response = JsonConvert.SerializeObject(rsp);
                payInfo = rsp["payinfo"];
                LogHelper.Info(NotifyUrl, "通联支付回调地址");
            }
            catch (Exception ex)
            {
                log.api_url = "ERROR";
                log.message = ex.Message;
                if (ex.Message == "订单已经支付")
                {
                    log.api_url = null;
                    log.request = "通联 接收异步支付通知";
                    log.response = "通联 接收异步支付通知";
                    new Core.BLL.PrepaidOrder().HandleOrder(order.order_id, Convert.ToDecimal(trxamt) / 100, order.order_id, Entity.Enums.PayType.Tonglian);
                }
            }
            Core.Payment.PayUtil.WriteOrderPayLog(log);
            return payInfo;
        }
        private string GerPayNotifyUrl(string actionName)
        {
            return WxpayConfig.WxPayNotifyUrl;
            //return "http://220.250.25.36:8123/notify/xmyzt";
            //var port = Request.Url.Port;
            //var url = "http://" + Request.Url.Host
            //        + (port > 0 && port != 80 ? string.Format(":{0}", port) : string.Empty)
            //        + "/TonglianPay/" + actionName;
            //return url;
        }
        #endregion
        #region 微信JSAPI支付

      
        /// <summary>
        /// 获取支付订单号
        /// </summary>
        /// <param name="order_sn">原订单号</param>
        /// <returns></returns>
        private string GetPayOrderNO(string order_sn)
        {
            return order_sn;
            //return string.Format("{0}_{1:yyMMddHHmm}", order_sn, DateTime.Now);
        }
        private string GetWxPayConfig()
        {
            try
            {
                WxpayClient client = new WxpayClient();
                WxpayJsConfigModel config = client.GetJSConfigModel(Request.Url.OriginalString);
                config.WxAppID = WxpayConfig.AppID;
                return Util.Conv.ToJson(config);
            }
            catch (Exception ex)
            {
                Core.LogHelper.Error(ex, "GetWxPayConfig失败");
                throw;
            }
        }
        /// <summary>
        /// 获取JSAPI 支付调用的参数模型
        /// </summary>
        /// <param name="order">订单信息</param>
        /// <returns></returns>
        private WxpayJSParams GetWxPayJSParams(Entity.Order_info order, string openid)
        {

            //初始化JSAPI参数
            WxpayJSParams jsParams = new WxpayJSParams();
            jsParams.TimesTamp = Util.Comm.GetTimeStamp().ToString();
            jsParams.NonceStr = WxpayHelper.GetNoncestr();
            jsParams.Package = "";
            jsParams.SignType = "MD5";
            jsParams.PaySign = "";

            string payOrderNO = this.GetPayOrderNO(order.order_id);
            WxpayClient client = new WxpayClient();
            WxpayUnifiedOrderRequest request = new WxpayUnifiedOrderRequest();

            int port = Request.Url.Port;
            request.NotifyUrl = "http://" + Request.Url.Host
                + (port > 0 && port != 80 ? string.Format(":{0}", port) : string.Empty)
                + "/Pay/WxpayNotify";

            request.DeviceInfo = "WEB";
            request.Body = "一卡通充值";
            request.OutTradeNo = payOrderNO; // order.order_sn;
            request.TotalFee = Convert.ToInt32(order.total_fee * 100);

            request.SpBillCreateIp = "8.8.8.8"; //客户端 IP Request.UserHostAddress;

            request.TimeStart = DateTime.Now.ToString("yyyyMMddHHmmss");
            request.TimeExpire = DateTime.Now.AddHours(1).ToString("yyyyMMddHHmmss"); //1小时后失效
            request.TradeType = "JSAPI";

            //补充openid
            request.OpenID = openid;

            // string codeUrl = "";
            string errorStr = string.Empty;
            WxpayUnifiedOrderResponse response = client.ExecuteUnifiedOrderRequest(request);

            Entity.log log = new Entity.log();
            log.business_no = order.order_id;
            log.api_name = "微信下单";

            if (response != null)
            {
                if (response.ResultCode == "SUCCESS")
                {
                    Core.BLL.PrepaidOrder orderBll = new Core.BLL.PrepaidOrder();

                    //codeUrl = response.CodeUrl;
                    //order.pay_note = prefix + codeUrl;
                    //改动，以便支持JSAPI调用
                    var wxrsp = new WxpayUnifiedOrderParams();
                    wxrsp.CodeUrl = response.CodeUrl;
                    wxrsp.PrepayID = response.PrepayID;
                    wxrsp.TradeType = response.TradeType;
                    wxrsp.PrepayID = payOrderNO;

                    order.pay_note = WXPAY_UNIFIED_PARAM_PREFIX + Util.Conv.ToJson(wxrsp);

                    string updateError = string.Empty;
                    bool isSuccess = orderBll.Update(order);
                    if (!isSuccess)
                    {
                        errorStr = "更新订单的pay_note(微信统一下单响应信息)出错";
                    }
                    jsParams.Package = "prepay_id=" + response.PrepayID;
                    jsParams.PaySign = WxpayHelper.GetSign(jsParams.GetParameters(), WxpayConfig.WxPayKey);

                }
                else
                {
                    jsParams = new WxpayJSParams();
                    errorStr = "调用统一下单接口时，业务结果出错";

                }
            }
            else
            {
                jsParams = new WxpayJSParams();
                errorStr = "调用统一下单接口失败";
            }

            log.response = Util.Conv.ToJson(response);
            log.message = errorStr;

            Core.Payment.PayUtil.WriteOrderPayLog(log);

            return jsParams;
        }

        const string WXPAY_UNIFIED_PARAM_PREFIX = "Wx";

        #endregion

        //微信 接收异步支付通知
        [HttpPost]
        public ContentResult WxpayNotify()
        {

            string resultStr = WeChatParking.Core.Payment.PayUtil.GetRequestString(System.Web.HttpContext.Current);
            try
            {
                if (WxpayConfig.IsTonglianChannel)
                {
                    string order_id = "", trxid = "", trxstatus = "";
                    int trxamt = 0;
                    string[] resultArr = resultStr.Split('&');
                    foreach (var item in resultArr)
                    {
                        string[] val = item.Split('=');
                        if (val[0] == "cusorderid") order_id = val[1];
                        else if (val[0] == "trxamt") trxamt = Convert.ToInt32(val[1]);
                        else if (val[0] == "trxid") trxid = val[1];
                        else if (val[0] == "trxstatus") trxstatus = val[1];
                    }
                    if (trxstatus == "0000")
                    {
                        new Core.BLL.PrepaidOrder().HandleOrder(order_id, Convert.ToDecimal(trxamt) / 100, trxid, Entity.Enums.PayType.Tonglian);
                    }
                    var log = new Entity.log()
                    {
                        business_no = order_id,
                        request = resultStr,
                        message = resultStr,
                        api_name = "微信通联支付回调",
                        pay_type = (short)Entity.Enums.PayType.Tonglian
                    };
                    Core.Payment.PayUtil.WriteOrderPayLog(log);
                    var result = "SUCCESS";
                    return Content(JsonConvert.SerializeObject(result, Formatting.None));
                }
                else
                {
                    WxpayNotifyResult result = XmlHelper.XmlDeserialize<WxpayNotifyResult>(resultStr);
                    WxpayNotifyReturn notifyRt = new WxpayNotifyReturn();
                    bool check = WxpayHelper.CheckSign(resultStr, WxpayConfig.WxPayKey, WxpayConfig.AppID, WxpayConfig.MchID);
                    if (check)
                    {
                        //处理业务逻辑，检查该支付信息对应的订单是否已被处理过
                        notifyRt.ReturnCode = "SUCCESS";

                        //支付成功，处理订单
                        new Core.BLL.PrepaidOrder().HandleOrder(result.OutTradeNo, Convert.ToDecimal(result.TotalFee) / 100, result.TransationID, Entity.Enums.PayType.Weixin);
                    }
                    else
                    {
                        notifyRt.ReturnCode = "FAIL";
                        notifyRt.ReturnMsg = "签名失败or参数格式校验错误";
                    }

                    var log = new Entity.log()
                    {
                        business_no = result.OutTradeNo,
                        request = resultStr,
                        message = Util.Conv.ToJson(notifyRt),
                        api_name = "微信支付回调",
                        pay_type = (short)Entity.Enums.PayType.Weixin
                    };

                    Core.Payment.PayUtil.WriteOrderPayLog(log);

                    return Content(XmlHelper.XmlSerialize(notifyRt));
                }

            }
            catch (Exception ex)
            {
                LogHelper.Error(ex, "接收异步支付通知");
                LogHelper.Info(resultStr, "接收异步支付通知");
                throw;
            }
        }


        /// <summary>
        /// 通联支付结果通知地址
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ContentResult TLpayNotify()
        {
            return Content(XmlHelper.XmlSerialize(null));
        }
        /// <summary>
        /// 通联退款结果通知地址
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ContentResult TLtkNotify()
        {
            return Content(XmlHelper.XmlSerialize(null));
        }
        /// <summary>
        /// 无感支付状态同步接口
        /// </summary>
        /// <returns></returns>
        public ContentResult WGpayNotify()
        {
            return Content(XmlHelper.XmlSerialize(null));
        }
        #region 微信扫码支付

        /// <summary>
        /// 获取二维码扫码链接
        /// </summary>
        /// <param name="order">订单信息</param>
        /// <returns></returns>
        public string GetWxPayCodeUrl(Entity.Order_info order)
        {
            var log = new Entity.log()
            {
                business_no = order.order_id,
                pay_type = (short)Entity.Enums.PayType.Weixin
            };

            //由于获取二维码扫码链接时，同一个订单号只能得到一个地址，所以首次获取的地址存在pay_note字段中，
            //先取pay_note字段判断是否有WxcodeUrl，没有时向微信提交新请求
            WxpayUnifiedOrderParams wxrsp = new WxpayUnifiedOrderParams();
            string prefix = "Wx";
            if (order.pay_note.IndexOf(prefix) >= 0)
            {
                string wxresponse = order.pay_note.Substring(prefix.Length);
                wxrsp = Util.Conv.ParseJson<WxpayUnifiedOrderParams>(wxresponse);
                return wxrsp.CodeUrl;
            }

            WxpayClient client = new WxpayClient();
            WxpayUnifiedOrderRequest request = new WxpayUnifiedOrderRequest();

            request.DeviceInfo = "WEB";
            request.Body = "一卡通充值";
            request.OutTradeNo = order.order_id;
            request.TotalFee = Convert.ToInt32(order.real_fee * 100);

            request.SpBillCreateIp = "8.8.8.8"; //客户端 IP Request.UserHostAddress;

            request.TimeStart = DateTime.Now.ToString("yyyyMMddhhmmss");
            request.TimeExpire = DateTime.Now.AddMinutes(30).ToString("yyyyMMddhhmmss"); //30分钟后失效
            request.TradeType = "NATIVE";

            string codeUrl = "";
            string errorStr = string.Empty;
            WxpayUnifiedOrderResponse response = client.ExecuteUnifiedOrderRequest(request);

            log.api_name = "微信统一下单接口";
            log.request = Util.Conv.ToJson(request);

            if (response != null)
            {
                log.response = Util.Conv.ToJson(response);

                if (response.ResultCode == "SUCCESS")
                {
                    codeUrl = response.CodeUrl;
                    //order.pay_note = prefix + codeUrl;
                    //改动，以便支持JSAPI调用
                    wxrsp.CodeUrl = response.CodeUrl;
                    wxrsp.PrepayID = response.PrepayID;
                    wxrsp.TradeType = response.TradeType;

                    order.pay_note = prefix + Util.Conv.ToJson(wxrsp);
                    //  Core.DAL.Pay_orderDAL.Instance.Update(order);

                }
                else
                {
                    errorStr = "调用统一下单接口时，业务结果出错";
                }
            }
            else
            {
                errorStr = "调用统一下单接口失败";
            }

            log.message = errorStr;

            Core.Payment.PayUtil.WriteOrderPayLog(log);


            return codeUrl;
        }


        public ActionResult RefreshPayStatus(string orderId)
        {
            var orderBll = new Core.BLL.PrepaidOrder();
            var order = orderBll.GetOrder(orderId);

            if (order == null)
            {
                return Fail("订单不存在");
            }

            if (order.pay_status == (short)WeChatParking.Entity.Enums.PayStatus.Payed)
            {
                return OK();
            }

            WxpayClient client = new WxpayClient();
            var rsp = client.ExecuteQueryOrderRequest(orderId);
            if (rsp == null || rsp.ResultCode != "SUCCESS" || rsp.ReturnCode != "SUCCESS" || rsp.TradeState != "SUCCESS")
            {
                return Fail("订单未支付");
            }
            try
            {
                new Core.BLL.PrepaidOrder().HandleOrder(rsp.OutTradeNo, Convert.ToDecimal(rsp.TotalFee) / 100, rsp.TransationID, Entity.Enums.PayType.Weixin);
                return OK();
            }
            catch (Exception ex)
            {
                return Fail(ex.Message);
            }
        }

        public ActionResult TestQueryOrderPayStatusByTransId(string transId)
        {
            WxpayClient client = new WxpayClient();
            var rsp = client.ExecuteQueryOrderRequestByTransactionID(transId);
            if (rsp == null || rsp.ResultCode != "SUCCESS" || rsp.ReturnCode != "SUCCESS" || rsp.TradeState != "SUCCESS")
            {
                return Fail("订单未支付");
            }
            try
            {
                // new Core.BLL.PrepaidOrder().HandleOrder(rsp.OutTradeNo, Convert.ToDecimal(rsp.TotalFee) / 100, rsp.TransationID, Entity.Enums.PayType.Weixin);
                return OK();
            }
            catch (Exception ex)
            {
                return Fail(ex.Message);
            }
        }

        public ActionResult TestQueryOrder(List<string> orderIds)
        {
            WxpayClient client = new WxpayClient();
            foreach (var orderId in orderIds)
            {
                client.ExecuteQueryOrderRequest(orderId);
            }
            return OK("YES");
        }

        #endregion

       
    }
}
